package com.clarence.dada.modular.system.resource.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.base.PageResult;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.enums.YesOrNotEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.factory.PageFactory;
import com.clarence.dada.core.factory.PageResultFactory;
import com.clarence.dada.modular.system.resource.entity.SysResourceEntity;
import com.clarence.dada.modular.system.resource.entity.req.SysResourceReq;
import com.clarence.dada.modular.system.resource.entity.resp.SysResourceResp;
import com.clarence.dada.modular.system.resource.mapper.SysResourceMapper;
import com.clarence.dada.modular.system.resource.service.SysResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 资源表 服务实现类
 *
 * @author GD
 * @since 2020/11/23 22:45
 */
@Service
@Slf4j
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResourceEntity> implements SysResourceService {
    //
//    @Resource
//    private RoleServiceApi roleServiceApi;
//
//    @Resource(name = "resourceCache")
//    private RedisOperatorApi<ResourceDefinition> resourceCache;
//
    @Override
    public void resourceAdd(SysResourceReq req) {
        SysResourceEntity sysResource = Convert.convert(SysResourceEntity.class, req);
        this.save(sysResource);
    }

    @Override
    public void resourceEdit(SysResourceReq req) {
        SysResourceEntity sysResource = this.querySysResource(req);
        BeanUtil.copyProperties(req, sysResource);
        this.updateById(sysResource);
    }

    @Override
    public SysResourceResp resourceDetail(SysResourceReq req){
        SysResourceEntity sysResource = querySysResource(req);
        return Convert.convert(SysResourceResp.class, sysResource);
    }


    @Override
    public void resourceDelete(SysResourceReq req) {
        SysResourceEntity sysResource = this.querySysResource(req);
        sysResource.setDelFlag(YesOrNotEnum.Y.getCode());
        this.updateById(sysResource);
    }

    @Override
    public PageResult<SysResourceResp> resourcePage(SysResourceReq req) {
        LambdaQueryWrapper<SysResourceEntity> wrapper = createWrapper(req);
        Page<SysResourceEntity> page = this.page(PageFactory.defaultPage(), wrapper);
        List<SysResourceResp> respList = Convert.convert(new TypeReference<>() {}, page.getRecords());
        return PageResultFactory.result(page, respList);
    }

    public SysResourceEntity querySysResource(SysResourceReq req) {
        SysResourceEntity sysResource = this.getById(req.getResourceId());
        if (ObjectUtil.isEmpty(sysResource) || sysResource.getDelFlag().equals(YesOrNotEnum.Y.getCode())) {
            throw new BusException(ErrorEnum.RESOURCE_NOT_EXIST);
        }
        return sysResource;
    }

//    @Override
//    public List<SysResourceEntity> findList(SysResourceReq req) {
//
//        LambdaQueryWrapper<SysResourceEntity> wrapper = createWrapper(req);
//
//        // 只查询code和name
//        wrapper.select(SysResourceEntity::getResourceCode, SysResourceEntity::getResourceName);
//
//        List<SysResourceEntity> menuResourceList = this.list(wrapper);
//
//        // 增加返回虚拟菜单的情况
//        SysResourceEntity sysResource = new SysResourceEntity();
//        sysResource.setResourceCode("");
//        sysResource.setResourceName("虚拟目录(空)");
//        menuResourceList.add(0, sysResource);
//
//        return menuResourceList;
//    }
//
//    @Override
//    public List<ResourceTreeNode> getRoleResourceTree(Long roleId, Boolean treeBuildFlag, Integer resourceBizType) {
//
//        // 查询当前角色已有的接口
//        List<SysRoleResourceDTO> resourceList = roleServiceApi.getRoleResourceList(Collections.singletonList(roleId));
//
//        // 该角色已拥有权限
//        List<String> alreadyList = new ArrayList<>();
//        for (SysRoleResourceDTO sysRoleResponse : resourceList) {
//            alreadyList.add(sysRoleResponse.getResourceCode());
//        }
//
//        return this.getResourceList(alreadyList, treeBuildFlag, resourceBizType);
//    }
//
//    @Override
//    public List<ResourceTreeNode> getResourceList(List<String> resourceCodes, Boolean treeBuildFlag, Integer resourceBizType) {
//        List<ResourceTreeNode> res = new ArrayList<>();
//
//        // 获取所有的资源
//        LambdaQueryWrapper<SysResourceEntity> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        sysResourceLambdaQueryWrapper.select(SysResourceEntity::getAppCode, SysResourceEntity::getModularCode, SysResourceEntity::getModularName, SysResourceEntity::getResourceCode, SysResourceEntity::getUrl, SysResourceEntity::getResourceName);
//
//        // 只查询需要授权的接口
//        sysResourceLambdaQueryWrapper.eq(SysResourceEntity::getRequiredPermissionFlag, YesOrNotEnum.Y.getCode());
//
//        // 查询指定范围的资源
//        sysResourceLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(resourceBizType), SysResourceEntity::getResourceBizType, resourceBizType);
//
//        LoginUserService loginUserService = LoginContext.me();
//        if (!loginUserService.getSuperAdminFlag()) {
//            // 获取权限列表
//            List<Long> roleIds = loginUserService.getLoginUser().getSimpleRoleInfoList().parallelStream().map(SimpleRoleInfo::getRoleId).collect(Collectors.toList());
//            Set<String> resourceCodeList = roleServiceApi.getRoleResourceCodeList(roleIds);
//            if (!resourceCodeList.isEmpty()) {
//                sysResourceLambdaQueryWrapper.in(SysResourceEntity::getResourceCode, resourceCodeList);
//            }
//        }
//
//        List<SysResourceEntity> allResource = this.list(sysResourceLambdaQueryWrapper);
//
//        // 根据模块名称把资源分类
//        Map<String, List<SysResourceEntity>> modularMap = new HashMap<>();
//        for (SysResourceEntity sysResource : allResource) {
//            List<SysResourceEntity> sysResources = modularMap.get(sysResource.getModularName());
//
//            // 没有就新建一个
//            if (ObjectUtil.isEmpty(sysResources)) {
//                sysResources = new ArrayList<>();
//                modularMap.put(sysResource.getModularName(), sysResources);
//            }
//            // 把自己加入进去
//            sysResources.add(sysResource);
//        }
//
//        // 创建一级节点
//        for (Map.Entry<String, List<SysResourceEntity>> entry : modularMap.entrySet()) {
//            ResourceTreeNode item = new ResourceTreeNode();
//            item.setResourceFlag(false);
//            String id = IdWorker.get32UUID();
//            item.setCode(id);
//            item.setParentCode(RuleConstants.TREE_ROOT_ID.toString());
//            item.setNodeName(entry.getKey());
//
//            // 设置临时变量，统计半开状态
//            int checkedNumber = 0;
//
//            //创建二级节点
//            for (SysResourceEntity resource : entry.getValue()) {
//                ResourceTreeNode subItem = new ResourceTreeNode();
//                // 判断是否已经拥有
//                if (!resourceCodes.contains(resource.getResourceCode())) {
//                    subItem.setChecked(false);
//                } else {
//                    checkedNumber++;
//
//                    // 让父类也选择
//                    item.setChecked(true);
//                    subItem.setChecked(true);
//                }
//                subItem.setResourceFlag(true);
//                subItem.setNodeName(resource.getResourceName());
//                subItem.setCode(resource.getResourceCode());
//                subItem.setParentCode(id);
//                res.add(subItem);
//            }
//
//            // 统计选中的数量
//            if (checkedNumber == 0) {
//                item.setChecked(false);
//                item.setIndeterminate(false);
//            } else if (checkedNumber == entry.getValue().size()) {
//                item.setChecked(true);
//                item.setIndeterminate(false);
//            } else {
//                item.setChecked(false);
//                item.setIndeterminate(true);
//            }
//
//            res.add(item);
//        }
//
//        // 根据map组装资源树
//        if (treeBuildFlag) {
//            return new DefaultTreeBuildFactory<ResourceTreeNode>().doTreeBuild(res);
//        } else {
//            return res;
//        }
//    }
//
//    @Override
//    public ResourceDefinition getApiResourceDetail(SysResourceVo sysResourceVo) {
//        LambdaQueryWrapper<SysResourceEntity> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        sysResourceLambdaQueryWrapper.eq(SysResourceEntity::getResourceCode, sysResourceVo.getResourceCode());
//        SysResourceEntity sysResource = this.getOne(sysResourceLambdaQueryWrapper);
//        if (sysResource != null) {
//
//            // 实体转化为ResourceDefinition
//            ResourceDefinition resourceDefinition = ResourceFactory.createResourceDefinition(sysResource);
//
//            // 填充具体的提示信息
//            return ResourceFactory.fillResourceDetail(resourceDefinition);
//        } else {
//            return null;
//        }
//    }
//
//    @Override
//    public void deleteResourceByProjectCode(String projectCode) {
//        LambdaQueryWrapper<SysResourceEntity> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(SysResourceEntity::getProjectCode, projectCode);
//        this.remove(wrapper);
//    }
//
//    @Override
//    public void updateResourceAppCode(String newAppCode) {
//        // 获取所有资源表信息
//        List<SysResourceEntity> list = this.list();
//
//        // 批量更新资源编码
//        for (SysResourceEntity sysResource : list) {
//            String newResourceCode = GunsResourceCodeUtil.replace(sysResource.getResourceCode(), newAppCode);
//            sysResource.setResourceCode(newResourceCode);
//        }
//
//        this.updateBatchById(list);
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void reportResources(@RequestBody ReportResourceParam reportResourceReq) {
//        this.reportResourcesAndGetResult(reportResourceReq);
//    }
//
//    @Override
//    public List<SysResourcePersistencePojo> reportResourcesAndGetResult(ReportResourceParam reportResourceReq) {
//        String projectCode = reportResourceReq.getProjectCode();
//        Map<String, Map<String, ResourceDefinition>> resourceDefinitions = reportResourceReq.getResourceDefinitions();
//
//        if (ObjectUtil.isEmpty(projectCode) || resourceDefinitions == null) {
//            return new ArrayList<>();
//        }
//
//        // 根据project删除该项目下的所有资源
//        this.deleteResourceByProjectCode(projectCode);
//
//        // 获取当前应用的所有资源
//        ArrayList<SysResourceEntity> allResources = new ArrayList<>();
//        ArrayList<ResourceDefinition> resourceDefinitionArrayList = new ArrayList<>();
//        for (Map.Entry<String, Map<String, ResourceDefinition>> appModularResources : resourceDefinitions.entrySet()) {
//            Map<String, ResourceDefinition> value = appModularResources.getValue();
//            for (Map.Entry<String, ResourceDefinition> modularResources : value.entrySet()) {
//                resourceDefinitionArrayList.add(modularResources.getValue());
//                SysResourceEntity resource = ResourceFactory.createResource(modularResources.getValue());
//                allResources.add(resource);
//            }
//        }
//
//        // 将资源存入库中
//        DbTypeEnum currentDbType = DbOperatorContext.me().getCurrentDbType();
//        if (DbTypeEnum.MYSQL.equals(currentDbType)) {
//            // 分批插入记录
//            List<List<SysResourceEntity>> split = ListUtil.split(allResources, RuleConstants.DEFAULT_BATCH_INSERT_SIZE);
//            for (List<SysResourceEntity> sysResources : split) {
//                this.getBaseMapper().insertBatchSomeColumn(sysResources);
//            }
//        } else {
//            this.saveBatch(allResources, allResources.size());
//        }
//
//        // 将资源存入缓存一份
//        Map<String, ResourceDefinition> resourceDefinitionMap = ResourceFactory.orderedResourceDefinition(resourceDefinitionArrayList);
//        for (Map.Entry<String, ResourceDefinition> entry : resourceDefinitionMap.entrySet()) {
//            resourceCache.put(entry.getKey(), entry.getValue());
//        }
//
//        // 组装返回结果
//        ArrayList<SysResourcePersistencePojo> finalResult = new ArrayList<>();
//        for (SysResourceEntity item : allResources) {
//            SysResourcePersistencePojo sysResourcePersistencePojo = new SysResourcePersistencePojo();
//            BeanUtil.copyProperties(item, sysResourcePersistencePojo);
//            finalResult.add(sysResourcePersistencePojo);
//        }
//
//        return finalResult;
//    }
//
//    @Override
//    public ResourceDefinition getResourceByUrl(@RequestBody ResourceUrlParam resourceUrlReq) {
//        if (ObjectUtil.isEmpty(resourceUrlReq.getUrl())) {
//            return null;
//        } else {
//
//            // 先从缓存中查询
//            ResourceDefinition tempCachedResourceDefinition = resourceCache.get(resourceUrlReq.getUrl());
//            if (tempCachedResourceDefinition != null) {
//                return tempCachedResourceDefinition;
//            }
//
//            // 缓存中没有去数据库查询
//            List<SysResourceEntity> resources = this.getBaseMapper().selectList(new QueryWrapper<SysResourceEntity>().eq("url", resourceUrlReq.getUrl()));
//
//            if (resources == null || resources.isEmpty()) {
//                return null;
//            } else {
//
//                // 获取接口资源信息
//                SysResourceEntity resource = resources.get(0);
//                ResourceDefinition resourceDefinition = new ResourceDefinition();
//                BeanUtils.copyProperties(resource, resourceDefinition);
//
//                // 获取是否需要登录的标记, 判断是否需要登录，如果是则设置为true,否则为false
//                String requiredLoginFlag = resource.getRequiredLoginFlag();
//                resourceDefinition.setRequiredLoginFlag(YesOrNotEnum.Y.name().equals(requiredLoginFlag));
//
//                // 获取请求权限的标记，判断是否有权限，如果有则设置为true,否则为false
//                String requiredPermissionFlag = resource.getRequiredPermissionFlag();
//                resourceDefinition.setRequiredPermissionFlag(YesOrNotEnum.Y.name().equals(requiredPermissionFlag));
//
//                // 查询结果添加到缓存
//                resourceCache.put(resourceDefinition.getUrl(), resourceDefinition);
//
//                return resourceDefinition;
//            }
//        }
//    }
//
    @Override
    public Set<String> getResourceUrlsListByCodes(Set<String> resourceCodes) {

        if (resourceCodes == null || resourceCodes.isEmpty()) {
            return new HashSet<>();
        }

        // 拼接in条件
        LambdaQueryWrapper<SysResourceEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysResourceEntity::getResourceCode, resourceCodes);
        queryWrapper.select(SysResourceEntity::getUrl);

        // 获取资源详情
        List<SysResourceEntity> list = this.list(queryWrapper);
        return list.stream().map(SysResourceEntity::getUrl).collect(Collectors.toSet());
    }
//
//    @Override
//    public Integer getResourceCount() {
//        long count = this.count();
//        return Convert.toInt(count);
//    }
//
//    @Override
//    public List<SysRoleResourceDTO> getTotalResourceCode(ResBizTypeEnum resBizTypeEnum) {
//
//        LambdaQueryWrapper<SysResourceEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(SysResourceEntity::getResourceCode, SysResourceEntity::getResourceBizType);
//
//        // 根据资源类型查询
//        queryWrapper.eq(ObjectUtil.isNotEmpty(resBizTypeEnum), SysResourceEntity::getResourceBizType, resBizTypeEnum.getCode());
//
//        List<SysResourceEntity> list = this.list(queryWrapper);
//
//        ArrayList<SysRoleResourceDTO> results = new ArrayList<>();
//        for (SysResourceEntity sysResource : list) {
//            SysRoleResourceDTO sysRoleResourceDTO = new SysRoleResourceDTO();
//            sysRoleResourceDTO.setResourceCode(sysResource.getResourceCode());
//            sysRoleResourceDTO.setResourceBizType(sysResource.getResourceBizType());
//            results.add(sysRoleResourceDTO);
//        }
//
//        return results;
//    }
//
//    @Override
//    public Integer getResourceBizTypeByCode(String resCode) {
//        LambdaQueryWrapper<SysResourceEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(SysResourceEntity::getResourceBizType);
//        queryWrapper.eq(SysResourceEntity::getResourceCode, resCode);
//        SysResourceEntity one = this.getOne(queryWrapper, false);
//        if (one == null) {
//            return ResBizTypeEnum.DEFAULT.getCode();
//        } else {
//            return one.getResourceBizType();
//        }
//    }

    /**
     * 创建wrapper
     *
     * @author GD
     * @since 2020/11/6 10:16
     */
    private LambdaQueryWrapper<SysResourceEntity> createWrapper(SysResourceReq req) {
        LambdaQueryWrapper<SysResourceEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(SysResourceEntity::getDelFlag, YesOrNotEnum.Y.name());

        if (ObjectUtil.isEmpty(req)) {
            return queryWrapper;
        }
        queryWrapper.eq(ObjectUtil.isNotEmpty(req.getAppCode()), SysResourceEntity::getAppCode, req.getAppCode());
        queryWrapper.like(ObjectUtil.isNotEmpty(req.getResourceName()), SysResourceEntity::getResourceName, req.getResourceName());
        queryWrapper.like(ObjectUtil.isNotEmpty(req.getUrl()), SysResourceEntity::getUrl, req.getUrl());
        return queryWrapper;
    }
//
//    /**
//     * 创建模块code和name的映射
//     *
//     * @author GD
//     * @since 2020/12/21 11:23
//     */
//    private Map<String, String> createModularCodeName(List<SysResourceEntity> resources) {
//        HashMap<String, String> modularCodeName = new HashMap<>();
//        for (SysResourceEntity resource : resources) {
//            modularCodeName.put(resource.getModularCode(), resource.getModularName());
//        }
//        return modularCodeName;
//    }

}
